package com.example.latch;

import com.example.service.HazelcastService;
import com.hazelcast.core.HazelcastInstanceNotActiveException;
import com.hazelcast.cp.lock.FencedLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

/*
 * @className: HazelcastLockLatch
 * @author: chentao
 * @date: 2025/2/19 上午9:17
 * @Version: 1.0
 * @description:
 */
public class HazelcastLockLatch {

    Logger logger = LoggerFactory.getLogger(getClass());

    private FencedLock fencedLock;

    //锁的名称
    private String name;

    //默认3秒尝试一次
    private long timeOut = 5;

    //锁定时间单位
    private TimeUnit timeUnit = TimeUnit.SECONDS;

    private HazelcastService hazelcastService;

    private LatchListener latchListener;

    private Thread thread;

    public HazelcastLockLatch(String name, HazelcastService hazelcastService, LatchListener latchListener) {
        this.name = name;
        this.hazelcastService = hazelcastService;
        this.latchListener = latchListener;
    }

    public HazelcastLockLatch(String name, long timeOut, HazelcastService hazelcastService, LatchListener latchListener) {
        this.name = name;
        this.timeOut = timeOut;
        this.hazelcastService = hazelcastService;
        this.latchListener = latchListener;
    }

    /***
     * 启动程序并加载
     * @throws Exception
     */
    public void start() {
        this.thread = new Thread(new Runnable() {
            @Override
            public void run() {
                boolean triedLock = false;
                try {
                    fencedLock = hazelcastService.getLock(name);
                    do {
                        triedLock = fencedLock.tryLock(timeOut, timeUnit);
                    } while (!triedLock);
                    latchListener.isMaster();
                } catch (Exception e) {
                    if (!(e instanceof HazelcastInstanceNotActiveException)) {
                        logger.warn("fencedLock锁获取失败: {}", e.getMessage());
                    }
                } finally {
                    if (fencedLock != null && fencedLock.isLocked()) {
                        fencedLock.unlock();
                    }
                }
            }
        });
        this.thread.setName("LockLatch-" + name);
        this.thread.start();
    }

    /***
     * 停止并回收资源
     * @throws Exception
     */
    public void stop() {
        try {
            if (this.fencedLock != null && this.fencedLock.isLocked()) {
                this.fencedLock.unlock();
            }
        } catch (Exception e) {
            if (!(e instanceof HazelcastInstanceNotActiveException)) {
                logger.warn("锁的释放异常: " + e.getMessage());
            }
        }
        if (this.thread != null) {
            this.thread.interrupt();
        }
    }
}
